home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Interactive Reference Guide
/
C-C++ Interactive Reference Guide.iso
/
c_ref
/
csource5
/
357_01
/
cstar1.exe
/
IN.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-06-18
|
11KB
|
474 lines
/* C* input qualification routines.
source: in.c
started: October 26, 1985
version:
February 22, 1989
PUBLIC DOMAIN SOFTWARE
The CSTAR program was placed in the public domain on June 15, 1991,
by its author and sole owner,
Edward K. Ream
1617 Monroe Street
Madison, WI 53711
(608) 257-0802
CSTAR may be used for any commercial or non-commercial purpose.
See cstar.h or cstar.c for a DISCLAIMER OF WARRANTIES.
*/
#include "cstar.h"
/*
Declare routines of this file.
*/
bool is_reserved (register char * name, int length);
struct x_ex * x_exists (struct node *q);
static bool am_match(register int mode, register struct node * loc);
static bool is_mpc (register struct node *p);
static bool is_m0 (register struct node *p);
static bool is_m1 (register struct node *p);
static bool is_m2 (register struct node *p);
static bool is_m3 (register struct node *p);
static bool is_m4 (register struct node *p);
static bool is_m5 (register struct node *p);
static bool is_m6 (register struct node *p);
static bool is_m70 (register struct node *p);
static bool is_m71 (register struct node *p);
static bool is_m72 (register struct node *p);
static bool is_m73 (register struct node *p);
static bool is_m74 (register struct node *p);
/*
Declare existence table defined in t2.s.
*/
extern int * x_lookup[];
/*
Declare the reserved word index table which are defined in t1.s
The dimension 2 is just a dummy value.
*/
#ifdef DRI
extern char * rwx_tab [2];
#else
extern struct t1_tab_struct * rwx_tab [2];
#endif
/*
Use the tables in t1.s to see if name[] contains a reserved word.
If so, set t_type, t_subtype and return TRUE.
Otherwise, set t_type to NULL and return FALSE.
*/
bool
is_reserved(register char * name, int length)
{
#ifdef DRI
register byte * p;
register char c;
#else
char c;
register struct t1_tab_struct * p;
register struct t1_entry_struct * e;
register int i, n;
int t;
#endif
TRACEP("is_reserved", printf("(%s, %d)\n", name, length));
c = *name;
if (c == '\0') {
goto not_found;
}
#ifdef DRI
/* Fetch the pointer. */
p = rwx_tab [c - 'A'];
/* Search for the proper subtable. */
for (;;) {
TRACEP("is_reserved", printf("rwx_tab subtable: p = %p\n", p));
if (p == NULL) {
goto not_found;
}
if (*(int *)p > length) {
goto not_found;
}
else if (length == *(int *)p) {
break;
}
else {
/* Point at the address of the next subtable. */
p += 2;
/* Fetch the address of the next subtable. */
p = * (char **) p;
}
}
TRACEP("is_reserved", printf("subtable found: p = %p\n", p));
while (*p != '\0') {
TRACEP("is_reserved", printf("compare: %s, %s\n", name, p));
TRACEP("is_reserved", printf("note: length = %d\n", length, p));
if(str_eq(name, p)) {
/* Found. */
p += length + 1;
t_type = (int) *p++;
t_subtype = (int) *p;
t_type &= 0xff;
t_subtype &= 0xff;
TRACEP("is_reserved",
printf("return %d, %d\n", t_type, t_subtype));
return TRUE;
}
/* Skip over the entry. */
p += length + 3;
TRACEP("is_reserved", printf("skip to: p = %p\n", p));
}
#else
/* Search for the proper subtable. */
for (p = rwx_tab [c - 'A']; ; p++) {
TRACEP("is_reserved", printf("p = %p\n", p));
if (p == NULL) {
goto not_found;
}
TRACEP("is_reserved", printf("p -> t_strlen = %d\n",
p -> t_strlen));
if (p == NULL || p -> t_strlen > length) {
goto not_found;
}
else if (p -> t_strlen == length) {
break;
}
}
/* A subtable with the right length has been found. */
n = p -> t_entries;
for (i = 0, e = p -> t_entry; i < n; e++, i++) {
TRACEP("is_reserved",
printf("compare: %s, %s\n", name, e -> e_string));
t = strcmp(name, e -> e_string);
if (t == 0) {
/* Found. */
t_type = ((int) (e -> e_arg1)) & 0xff;
t_subtype = ((int) (e -> e_arg2)) & 0xff;
TRACEP("is_reserved",
printf("return %d, %d\n", t_type, t_subtype));
return TRUE;
}
/* -----
else if (t > 0) {
goto not_found;
}
----- */
}
#endif
not_found:
t_type = 0;
t_subtype = 0;
TRACEP("is_reserved_ret", printf("ISR: returns 0\n"));
return FALSE;
}
/*
Use the tables in t2.s to determine whether a particular
operator operand combination exists
Return a pointer to a static structure containing various
results of the operation, including an operation
length to attach to the code node, a machine code, etc.
Return NULL if not found.
Op is the desired X_TOK, and arg1 and arg2 the arguments, if any.
*/
struct x_ex *
x_exists(struct node *q)
{
register struct node * arg1, * arg2;
register unsigned int val;
register int *p;
int op, l1, l2;
static struct x_ex x;
TRACEP("x_exists", printf("(%d, %p, %p)\n", op, arg1, arg2));
op = q -> n_xtype;
arg1 = q -> n_arg1;
arg2 = q -> n_arg2;
for (p = x_lookup[op]; p[0] >= 0 ;p += X_T_FRAME) {
TRACE("x_exists", printf("entry: %d, %d, %d, %d, %d, %d\n",
p[0], p[1], p[2], p[3], p[4], p[5]));
/* here we check address modes and continue if no good */
if (!am_match(p[3], arg1) || !am_match(p[4], arg2)) {
continue;
}
x.xlen = 0;
TRACEP("x_exists", printf("entry accepted\n"));
/* check up on first argument */
if (p[1] != NONE_AM) {
l1 = mlen(arg1);
if (p[1] > ANY_AM) {
/* is mode1 or mode2, and am_match will check */
/* see note in t2.c */
}
else if (l1 & ~p[1]) {
g_error(q, "argument length error");
return NULL;
}
if (p[0] == 1) {
x.xlen = (byte) l1;
}
}
/* check up on second argument */
if (p[2] != NONE_AM) {
l2 = mlen(arg2);
if (p[2] > ANY_AM) {
if (p[2] == AS_1_AM && l1 != l2) {
g_error(q, "length mismatch");
return NULL;
}
}
else if (l2 & ~p[2]) {
g_error(q, "argument length error");
return NULL;
}
if (p[0] == 2) {
x.xlen = (byte) l2;
}
}
return &x;
}
g_error(q, "opcode doesn't apply to operand combination");
return NULL;
}
/*
Return TRUE if loc_node is of the indicated address mode.
*/
static bool
am_match(register int mode, register struct node * loc)
{
TRACEP("am_match", printf("(mode %d, loc %p)\n", mode, loc));
/* make sure loc is nonnull */
if (loc == NULL) {
return mode == NONE_AM;
}
else if (loc -> n_type != ID_TOK) {
g_error(NULL, "internal: am_match: not a loc_node");
return FALSE;
}
/* here, loc is guaranteed to be nonnull */
/* WARNING: loc is a ULABEL?? (ULABELS don't even get looked up now) */
switch (mode) {
case NONE_AM: return FALSE;
case GEN_AM: return TRUE;
case MEM_AM: return !is_m0(loc) && !is_m1(loc);
case ALT_AM: return !is_mpc(loc) && !is_m74(loc);
case DALT_AM: return !is_m1(loc);
case MALT_AM: return !is_m0(loc) && !is_m1(loc) &&
!is_mpc(loc) && !is_m74(loc);
case DATA_AM: return !is_m1(loc);
case INC_AM: return is_m3(loc);
case DEC_AM: return is_m4(loc);
case DISP_AM: return is_m5(loc);
case CONTROL_AM: return !is_m0(loc) && !is_m1(loc) &&
!is_m3(loc) && !is_m4(loc) &&
!is_m74(loc);
case AN_AM: return is_m1(loc);
case DN_AM: return is_m0(loc);
case USP_AM: return 0; /* WARNING: */
case IMM_AM: return is_m74(loc);
/*
WARNING: these next tests will malfunction under some
circumstances when the local-name option is on, since they
don't check the offset implied by the name.
See x_addpsi(), resolve(), or gen_pp() for examples of how
this is done; it involves finding the offset in the parent
ID node. The interpretation and treatment of such offsets
depends somewhat on the storage class. If equates are put
in, a new storage class should be created for them.
*/
case IMM8_AM: return is_m74(loc) && !loc -> n_cid &&
loc -> n_const >= -128 && loc -> n_const <= 127;
case IMM16_AM: return is_m74(loc) && !loc -> n_cid &&
loc -> n_const >= -32768 && loc -> n_const <= 32767;
case Q8BIT_AM: return is_m74(loc) && !loc -> n_cid &&
loc -> n_const >= -128 && loc -> n_const <= 127;
case QUICK8_AM: return is_m74(loc) && !loc -> n_cid &&
loc -> n_const >= 1 && loc -> n_const <= 8;
case BIT31_AM: return is_m74(loc) && !loc -> n_cid &&
loc -> n_const >= 0 && loc -> n_const <= 31;
case TRAP15_AM: return is_m74(loc) && !loc -> n_cid &&
loc -> n_const >= 0 && loc -> n_const <= 15;
/* WARNING: how do we represent a reg list??? */
case MOVEM2R_AM:
case MOVER2M_AM:
case REGLIST_AM: return FALSE;
case CCR_AM: return loc && loc -> n_reg1 == R_CCR;
case SR_AM: return loc && loc -> n_reg1 == R_SR;
default:
printf("am_match: bad mode %d\n", mode);
fatal("");
}
}
/*
The following 16 routines follow page 79 of the 68000 book.
What they will eventually return, of course, is an index into a
set of sub-opcode bit masks.
*/
static bool
is_mpc(register struct node *p)
{
SL_DISABLE();
return p -> n_reg1 == R_PC;
}
static bool
is_m0(register struct node *p)
{
SL_DISABLE();
/* Data register. */
return !(p -> n_mode) && is_dreg(p -> n_reg1) && !p -> n_reg2;
}
static bool
is_m1(register struct node *p)
{
SL_DISABLE();
/* Address register. */
return !(p -> n_mode) && is_areg(p -> n_reg1) && !p -> n_reg2;
}
static bool
is_m2(register struct node *p)
{
SL_DISABLE();
/* Address register indirect. */
return p -> n_mode == EA_MODE && is_areg(p -> n_reg1) &&
!(p -> n_reg2) && !(p -> n_const);
}
static bool
is_m3(register struct node *p)
{
SL_DISABLE();
/* Address register indirect with post increment. */
return p -> n_mode == EAPSI_MODE;
}
static bool
is_m4(register struct node *p)
{
SL_DISABLE();
/* Address register indirect with pre decrement. */
return p -> n_mode == EAPRD_MODE;
}
static bool
is_m5(register struct node *p)
{
SL_DISABLE();
/* Address register indirect with displacement. */
return p -> n_mode == EA_MODE &&
is_areg(p -> n_reg1) && !(p -> n_reg2) && p -> n_const;
}
static bool
is_m6(register struct node *p)
{
SL_DISABLE();
/* Address register indirect with index. */
return p -> n_mode == EA_MODE &&
is_areg(p -> n_reg1) && p -> n_reg2;
}
static bool
is_m70(register struct node *p)
{
SL_DISABLE();
/* Absolute short. */
/* WARNING: all abolute long for now; this will take fiddling. */
/* note that since p is a loc_node, its C type is available, and
the constant value is also available */
return FALSE;
}
static bool
is_m71(register struct node *p)
{
SL_DISABLE();
/* Absolute long. */
return !(p -> n_mode) && p -> n_cid;
}
static bool
is_m72(register struct node *p)
{
SL_DISABLE();
/* Program counter with displacement. */
return p -> n_mode == EA_MODE &&
p -> n_reg1 == R_PC && !(p -> n_reg2);
}
static bool
is_m73(register struct node *p)
{
SL_DISABLE();
/* Program counter with index. */
return p -> n_mode == EA_MODE &&
p -> n_reg1 == R_PC && p -> n_reg2;
}
static bool
is_m74(register struct node *p)
{
SL_DISABLE();
/* Immediate. */
return !(p -> n_mode) && !(p -> n_reg1);
}